package repo

import (
	"context"
	"github.com/star-find-cloud/star-chat/message/domain"
	"github.com/star-find-cloud/star-chat/pkg/database"
	log "github.com/star-find-cloud/star-chat/pkg/logger"
)

type RepoImpl struct {
	db    database.Database
	cache *database.Redis
}

func NewRepo(db database.Database, cache *database.Redis) domain.Repo {
	return &RepoImpl{
		db:    db,
		cache: cache,
	}
}

func (r *RepoImpl) Upload(ctx context.Context, message *domain.Message) error {
	sqlStr := "insert into message(id, from_id, to_id, msg, type, token, from_ip, to_ip, createdAt) values ($1, $2, $3, $4, $5, $6, $7, $8, now());"
	_, err := r.db.GetDB().ExecContext(ctx, sqlStr, message.ID, message.FromID, message.ToID, message.Msg, message.Type, message.Token, message.FromIP, message.ToIP)
	if err != nil {
		log.SQLLogger.Errorf("创建消息失败: %v", err)
		return err
	}
	return nil
}

func (r *RepoImpl) GetByUserID(ctx context.Context, fromID, toID int) (*[]domain.Message, error) {
	sqlStr := "select id, from_id, to_id, msg, type, token, from_ip, to_ip, createdAt from message where from_id = $1 and to_id = $2;"
	var message *[]domain.Message

	err := r.db.GetDB().SelectContext(ctx, &message, sqlStr, fromID, toID)
	if err != nil {
		log.SQLLogger.Errorf("获取消息失败: %v", err)
		return nil, err
	}
	return message, nil
}

func (r *RepoImpl) GetByMsg(ctx context.Context, msg string, userID int) (*[]domain.Message, error) {
	sqlStr := "select id, from_id, to_id, msg, type, token, from_ip, to_ip, createdAt from message where msg_tsvector @@ to_tsquery('jiebacfg', $1) and (to_id = $2 or from_id = $2);"
	var message *[]domain.Message

	err := r.db.GetDB().SelectContext(ctx, &message, sqlStr, msg, userID)
	if err != nil {
		log.SQLLogger.Errorf("获取消息失败: %v", err)
		return nil, err
	}
	return message, nil
}

func (r *RepoImpl) Delete(ctx context.Context, id int64) error {
	sqlStr := "delete from message where id = $1;"

	_, err := r.db.GetDB().ExecContext(ctx, sqlStr, id)
	if err != nil {
		log.SQLLogger.Errorf("删除消息失败: %v", err)
		return err
	}
	return nil
}
